home *** CD-ROM | disk | FTP | other *** search
- #include <stdlib.h>
- #include <string.h>
- #include <limits.h>
- #include "../misc/misc.h"
- #include "askrunlevel.h"
- #include "../netconf/netconf.h"
- #include "../fstab/fstab.h"
- #include "../paths.h"
- #include "askrunlevel.m"
-
- static HELP_FILE help_lilo (HELP_ASKRUN,"lilo");
- static CONFIG_FILE f_lilo (ETC_LILO_CONF,help_lilo,CONFIGF_MANAGED);
- static CONFIG_FILE f_makefile (USR_SRC_LINUX_MAKEFILE,help_lilo,CONFIGF_NONE);
-
- /*
- One configuration
- */
- class LILO_PARM{
- public:
- int ramdisk; // Size of the ramdisk or no ramdisk
- char read_only;
- SSTRING vga;
- SSTRING root;
- SSTRING append;
- /*~PROTOBEG~ LILO_PARM */
- public:
- LILO_PARM (void);
- /*~PROTOEND~ LILO_PARM */
- };
-
- PUBLIC LILO_PARM::LILO_PARM()
- {
- ramdisk = 0;
- read_only = 1;
- }
-
- /*
- This represent one bootable linux configyration
- */
- class LILO_CONF: public ARRAY_OBJ{
- public:
- char must_be_deleted; // Is this entry obsoleted
- LILO_PARM parm;
- SSTRING image;
- SSTRING label;
- /*~PROTOBEG~ LILO_CONF */
- public:
- LILO_CONF (void);
- /*~PROTOEND~ LILO_CONF */
- };
-
- PUBLIC LILO_CONF::LILO_CONF()
- {
- must_be_deleted = 0;
- }
-
- class LILO_CONFS: public ARRAY{
- /*~PROTOBEG~ LILO_CONFS */
- public:
- LILO_CONF *getitem (int no);
- /*~PROTOEND~ LILO_CONFS */
- };
-
- PUBLIC LILO_CONF *LILO_CONFS::getitem(int no)
- {
- return (LILO_CONF*)ARRAY::getitem(no);
- }
-
- class LILO_OTHER: public ARRAY_OBJ{
- public:
- SSTRING label;
- SSTRING partition;
- };
- class LILO_OTHERS: public ARRAY{
- /*~PROTOBEG~ LILO_OTHERS */
- public:
- LILO_OTHER *getitem (int no);
- /*~PROTOEND~ LILO_OTHERS */
- };
-
- PUBLIC LILO_OTHER *LILO_OTHERS::getitem(int no)
- {
- return (LILO_OTHER*)ARRAY::getitem(no);
- }
-
- /* #Specification: lilo.conf / how it works
- The lilo.conf file is splitted in two sections. The first
- contain the global or default setting. This section
- act as a default for the rest of the file. This section ends
- with the first "image = " or "other = " statement.
-
- Global settings are:
-
- #
- compact
- delay
- boot = ...
- #
-
- Default setting that can be overriden in the followings
- image= are
-
- #
- ramdisk = x
- read-only
- read-write
- root = ...
- vga = ...
- #
- */
- struct LILO_CUR{
- LILO_CONF *conf;
- LILO_PARM *parm;
- LILO_OTHER *other;
- int noline;
- };
- class LILO {
- SSTRING boot; // On which device to place the boot code
- char compact; //Special boot mode
- int delay; // Delay in second or 0 for no delay
- LILO_PARM def; // Default value
- SSTRING message; // Path of the message file
- LILO_CONFS confs;
- LILO_OTHERS others;
- char prefix[PATH_MAX];
- public:
- char isvalid; // Tell if the configuration is usable or present
- char isused; // Is LILO used on this computer
- /*~PROTOBEG~ LILO */
- public:
- LILO (void);
- void addkernel (const char *def_src,
- const char *def_name);
- private:
- void compute_prefix (void);
- public:
- int edit (void);
- LILO_CONF *getconffromlabel (const char *lab);
- private:
- void makecfgpath (const char *path, char *realpath);
- void parse_eq (const char *keyw,
- const char *vals,
- LILO_CUR&cur);
- void parse_single (const char *pt, LILO_CUR&cur);
- public:
- int save (void);
- void setdefault (void);
- private:
- void setupedit (DIALOG&dia);
- void setupparm (DIALOG&dia, LILO_PARM&p);
- public:
- int updateif (void);
- private:
- int validate (int &nof);
- protected:
- void writeparm (FILE *fout,
- LILO_PARM&p,
- int global_parm);
- public:
- /*~PROTOEND~ LILO */
- };
-
-
- /*
- Parse keyword with a value
- */
- PRIVATE void LILO::parse_eq(
- const char *keyw,
- const char *vals,
- LILO_CUR &cur)
- {
- vals = str_skip (vals);
- char word[100];
- str_copyword (word,keyw);
- int numval = atoi(vals);
- if (strcmp(word,"ramdisk")==0){
- cur.parm->ramdisk = numval;
- }else if (strcmp(word,"delay")==0){
- delay = numval;
- }else if (strcmp(word,"boot")==0){
- boot.setfrom (vals);
- }else if (strcmp(word,"vga")==0){
- cur.parm->vga.setfrom (vals);
- }else if (strcmp(word,"message")==0){
- message.setfrom (vals);
- }else if (strcmp(word,"root")==0){
- cur.parm->root.setfrom (vals);
- }else if (strcmp(word,"append")==0){
- cur.parm->append.setfrom (vals);
- }else if (strcmp(word,"label")==0){
- if (cur.conf != NULL){
- cur.conf->label.setfrom (vals);
- }else if (cur.other != NULL){
- cur.other->label.setfrom (vals);
- }else{
- xconf_error ("Misplaced \"label\" statement\n"
- "in file %s, line %d",f_lilo.getpath()
- ,cur.noline);
- }
- }else if (strcmp(word,"image")==0){
- cur.conf = new LILO_CONF;
- cur.other = NULL;
- confs.add (cur.conf);
- cur.conf->image.setfrom (vals);
- cur.parm = &cur.conf->parm;
- cur.parm->read_only = def.read_only;
- }else if (strcmp(word,"other")==0){
- cur.other = new LILO_OTHER;
- cur.conf = NULL;
- others.add (cur.other);
- cur.other->partition.setfrom (vals);
- }
-
-
- }
- /*
- Interpret single word parameter line
- */
- PRIVATE void LILO::parse_single(const char *pt, LILO_CUR &cur)
- {
- char word[100];
- str_copyword (word,pt);
- if (strcmp(word,"compact")==0){
- compact = 1;
- }else if (strcmp(word,"read-only")==0){
- cur.parm->read_only = 1;
- }else if (strcmp(word,"read-write")==0){
- cur.parm->read_only = 0;
- }
- }
-
-
- PRIVATE void LILO::compute_prefix()
- {
- /* #Specification: lilo / moving lilo.conf
- Linuxconf check carefully the path of the configuration
- file (normally /etc/lilo.conf but changeable by the
- user).
-
- We assume that the path of the /boot/map is fairly
- fixed. The only option used with lilo is -r (by
- linuxconf at least), so lilo.conf is somewhere in
- a "etc" directory and the file "map" is somewhere
- in a "boot" directory right near this "etc".
- */
- const char *path = f_lilo.getpath();
- static char stdconf[]= ETC_LILO_CONF;
- if (strcmp (path,stdconf)==0){
- prefix[0] = '\0';
- }else{
- int len = strlen(stdconf);
- int newlen = strlen(path);
- int offset = newlen - len;
- if (newlen < len
- || strcmp(path+offset,stdconf)!=0){
- xconf_error (MSG_U(E_IVLDPATH
- ,"Invalid path of lilo.conf: %s\n"
- "expected something at least as long\n"
- "as %s\n"
- "and ending with %s")
- ,path,stdconf,stdconf);
- isvalid = 0;
- }else{
- strncpy (prefix,path,offset);
- prefix[offset] = '\0';
- }
- }
- }
-
- static char LILOCFG[]="lilo";
- static char ISUSED[]="isused";
-
- /*
- Load and parse the /etc/lilo.conf configuration file
- */
- PUBLIC LILO::LILO()
- {
- isvalid = 0;
- compact = 0;
- delay = 0;
- /* #Specification: lilo / disabling allowed
- As a default, linuxconf assume lilo is used to
- boot this computer. A check box allows the admin
- to turn lilo off. Linuxconf won't bother the check
- lilo further.
- */
- isused = linuxconf_getvalnum (LILOCFG,ISUSED,1);
- FILE *fin = f_lilo.fopen ("r");
- if (fin != NULL){
- char buf[1000];
- LILO_CUR cur;
- cur.parm = &def;
- cur.conf = NULL;
- cur.other = NULL;
- cur.noline = 0;
- /* #Specification: /etc/lilo.conf / comments
- Comments are not preserved when editing lilo.conf
- */
- isvalid = 1;
- while (fgets_strip(buf,sizeof(buf)-1,fin,&cur.noline)!=NULL){
- strip_end (buf);
- char *pt = str_skip (buf);
- if (*pt != '#' && *pt != '\0'){
- char *pteq = strchr(pt,'=');
- if (pteq != NULL){
- *pteq++ = '\0';
- parse_eq (pt,pteq,cur);
- }else{
- parse_single(pt,cur);
- }
- }
- }
- fclose (fin);
- }
- compute_prefix();
- }
-
-
- /*
- Locate one setup from its label
- */
- PUBLIC LILO_CONF *LILO::getconffromlabel (const char *lab)
- {
- LILO_CONF *ret = NULL;
- for (int i=0; i<confs.getnb(); i++){
- LILO_CONF *c = confs.getitem(i);
- if (c->label.cmp(lab)==0){
- ret = c;
- break;
- }
- }
- return ret;
- }
-
- /*
- Build a path using a path relative to the /etc/lilo.conf file.
- */
- PRIVATE void LILO::makecfgpath(const char *path, char *realpath)
- {
- if (prefix[0] == '\0'){
- strcpy (realpath,path);
- }else{
- strcpy (realpath,prefix);
- strcat (realpath,path);
- }
- }
-
- static void writeif (FILE *fout, SSTRING &s, const char *keyw)
- {
- if (!s.is_empty()) fprintf (fout," %s = %s\n",keyw,s.get());
-
- }
-
- PROTECTED void LILO::writeparm(
- FILE *fout,
- LILO_PARM &p,
- int global_parm) // Is p LILO::parm or
- // one of the LILO_CONF::parm ?
- {
- /* #Specification: lilo / writing lilo.conf / normalising
- linuxconf is not writing back lilo.conf in the same
- way it was read. It is somewhat normalising it.
- If for example, one setup has the same definitions
- than the default setup, the definition are not repeated.
- This feature is transparent to the user though. It make
- the file lilo.conf smaller and easier to read manually.
- */
- if (global_parm || p.ramdisk != def.ramdisk){
- fprintf (fout," ramdisk = %d\n",p.ramdisk);
- }
- if (p.vga.is_empty()){
- if (global_parm) fputs (" vga = normal\n",fout);
- }else{
- fprintf (fout," vga = %s\n",p.vga.get());
- }
- writeif (fout,p.append,"append");
- if (global_parm || def.root.is_empty()){
- writeif (fout,p.root,"root");
- }else if (!p.root.is_empty()
- && p.root.cmp(def.root)!=0){
- writeif (fout,p.root,"root");
- }
- if (global_parm || p.read_only != def.read_only){
- fputs (p.read_only ? " read-only\n" : " read-write\n"
- ,fout);
- }
- }
- /*
- Write back the /etc/lilo.conf file.
- Return -1 if any error.
- */
- PUBLIC int LILO::save()
- {
- int ret = -1;
- FILE *fout = f_lilo.fopen ("w");
- if (fout != NULL){
- fprintf (fout,"boot = %s\n",boot.get());
- if (delay != 0) fprintf (fout,"delay = %d\n",delay);
- if (compact) fprintf (fout,"compact\n");
- writeif (fout,message,"message");
- writeparm (fout,def,1);
- int i;
- for (i=0; i<confs.getnb(); i++){
- LILO_CONF *c = confs.getitem(i);
- if (!c->image.is_empty() && !c->must_be_deleted){
- fprintf (fout,"image = %s\n",c->image.get());
- fprintf (fout," label = %s\n",c->label.get());
- writeparm (fout,c->parm,0);
- }
- }
- for (i=0; i<others.getnb(); i++){
- LILO_OTHER *c = others.getitem(i);
- if (!c->partition.is_empty()){
- fprintf (fout,"other = %s\n"
- ,c->partition.get());
- fprintf (fout," label = %s\n"
- ,c->label.get());
- }
- }
- ret = fclose (fout);
- linuxconf_replace (LILOCFG,ISUSED,isused);
- linuxconf_save();
- }
- return ret;
- }
- static void lilo_setpart (FIELD_COMBO *comb)
- {
- PARTITIONS *parts = partition_load();
- for (int i=0; i<parts->getnb(); i++){
- PARTITION *p = parts->getitem(i);
- char str[80];
- p->formatinfo (str);
- comb->addopt(p->getdevice(),str);
- }
- }
-
- /*
- Dispose the parameter of a configuration or the default ones.
- */
- PRIVATE void LILO::setupparm (DIALOG &dia, LILO_PARM &p)
- {
- FIELD_COMBO *comb = dia.newf_combo (MSG_U(F_ROOTPART,"root partition")
- ,p.root);
- lilo_setpart (comb);
- dia.newf_num (MSG_U(F_RAMSIZE,"Ramdisk size"),p.ramdisk);
- dia.newf_chk (MSG_U(F_BOOTMODE,"boot mode"),p.read_only,"Read only");
- comb = dia.newf_combo (MSG_U(F_VGA,"VGA mode"),p.vga);
- comb->addopt (MSG_U(F_NORMAL,"normal"),MSG_U(F_STD8025,"standard 80x25"));
- dia.newf_str (MSG_U(F_BOOTOPT,"Boot options"),p.append);
- }
-
- /*
- Dispose the dialog
- */
- PRIVATE void LILO::setupedit (DIALOG &dia)
- {
- dia.newf_chk ("",isused,MSG_U(F_LILOUSED
- ,"LILO is used to boot this system"));
- FSTAB fstab;
- FIELD_COMBO *comb = dia.newf_combo (MSG_U(F_INSTBOOT
- ,"Install boot sector on"),boot);
- comb->addopt (fstab.getrootdev(),MSG_U(F_BOOTREC
- ,"boot record of the current root partition"));
- comb->addopt ("/dev/hda",MSG_U(F_MASTERIDE
- ,"Master boot record on IDE systems"));
- comb->addopt ("/dev/sda",MSG_U(F_MASTERSCSI
- ,"Master boot record on SCSI systems"));
- comb->addopt (MSG_U(F_FD0,"/dev/fd0"),"");
- lilo_setpart (comb);
- dia.newf_chk (MSG_U(F_BIOSMODE,"Bios boot mode"),compact,"Compact");
- dia.newf_num (MSG_U(F_BOOTDELAY,"Boot delay in 1/10 of seconds"),delay);
- dia.newf_str (MSG_U(F_MSGFILE,"Message file(opt)"),message);
- dia.newf_title ("",MSG_U(T_DEFAULTS,"Defaults"));
- setupparm (dia,def);
- /* #Specification: LILO editing / empty slots
- Linuxconf always add two more LILO_CONF records
- and two LILO_OTHER records, so the user is able
- to fill new one. Ideally a special buttons would
- be needed.
- */
- int i;
- for (i=0; i<2; i++){
- LILO_CONF *conf = new LILO_CONF;
- conf->parm.read_only = def.read_only;
- confs.add (conf);
- }
- for (i=0; i<2; i++)others.add (new LILO_OTHER);
- dia.newf_title ("",MSG_U(T_SETUPS,"Linux setups"));
- for (i=0; i<confs.getnb(); i++){
- if (i == 0){
- dia.newf_title ("",MSG_U(F_DEFBOOT,"Defaut Linux boot"));
- }else{
- dia.newf_title ("","-");
- }
- LILO_CONF *c = confs.getitem(i);
- dia.newf_chk ("",c->must_be_deleted
- ,MSG_U(F_DELCFG,"Delete this configuration"));
- dia.newf_str (MSG_U(F_LABEL,"Label"),c->label);
- dia.newf_str (MSG_U(F_KERNELIMAGE,"Kernel image file"),c->image);
- setupparm (dia,c->parm);
- }
- dia.newf_title ("",MSG_U(F_OTHEROS,"Other operating systems"));
- for (i=0; i<others.getnb(); i++){
- if (i != 0) dia.newf_title ("","-");
- LILO_OTHER *c = others.getitem(i);
- dia.newf_str (MSG_R(F_LABEL),c->label);
- FIELD_COMBO *comb = dia.newf_combo (MSG_U(F_PARTBOOT
- ,"partition to boot")
- ,c->partition);
- lilo_setpart (comb);
- }
- }
-
- static int validate_parm(
- LILO_PARM &p,
- int complain_if_empty)
- {
- PARTITIONS *parts = partition_load();
- int ret = -1;
- if (!p.root.is_empty()){
- const char *pr = p.root.get();
- PARTITION *e = parts->getitem(pr);
- if (strncmp(pr,"/dev/fd",7)==0){
- ret = 0;
- }else if (e == NULL || !e->islinux()){
- xconf_error (MSG_U(E_IVLDPART,"Partition %s is either invalid\n"
- "or not a linux partition\n"),pr);
- }else{
- ret = 0;
- }
- }else if(complain_if_empty){
- xconf_error (MSG_U(E_ROOTPNEED,"You must specify the root partition"));
- }else{
- ret = 0;
- }
- return ret;
- }
-
-
- /*
- Sanity check of the complete configuration
- Return -1 if any error.
- nof will contain the number of the faulty field.
- */
- PRIVATE int LILO::validate(int &nof)
- {
- validate_parm (def,0);
- int i;
- int ret = 0;
- PARTITIONS *parts = partition_load();
- if (boot.cmp("/dev/fd0")!=0
- && boot.cmp("/dev/hda")!=0
- && boot.cmp("/dev/sda")!=0
- && parts->getitem(boot.get())==NULL){
- xconf_error (MSG_U(E_IVLSECTOR
- ,"Invalid partition or device for boot sector\n"
- "installation"));
- nof = 0;
- ret = -1;
- }
- if (ret == 0){
- for (i=0; i<confs.getnb() && ret == 0; i++){
- LILO_CONF *c = confs.getitem(i);
- if (!c->image.is_empty() && !c->must_be_deleted){
- ret = validate_parm (c->parm
- ,def.root.is_empty());
- // This computation is completly dependant on
- // the dialog layout.
- if (ret != 0) nof = i*8 + 13;
- }
- }
- }
- return ret;
- }
-
-
- PUBLIC int LILO::edit()
- {
- int nof = 0;
- int ret = -1;
- while (1){
- DIALOG dia;
- setupedit (dia);
- MENU_STATUS code = dia.edit (
- MSG_U(T_LILOCONF,"LInux LOader configuration")
- ,MSG_U(I_LILOCONF,"You are allowed to specify\n"
- "-how it boots\n"
- "-where (which partition)\n"
- "-and what (LILO can boot almost any OS)")
- ,help_lilo
- ,nof
- ,MENUBUT_ACCEPT|MENUBUT_CANCEL|MENUBUT_INS);
- if (code == MENU_ESCAPE || code == MENU_CANCEL){
- break;
- }else if (code == MENU_INS){
- confs.insert (0,new LILO_CONF);
- }else if (code == MENU_ACCEPT){
- if (validate(nof)!=-1){
- ret = save();
- break;
- }
- }
- }
- return ret;
- }
-
- int lilo_edit ()
- {
- LILO lilo;
- int ret = lilo.edit();
- if (ret == 0) lilo.updateif();
- return ret;
- }
-
- /*
- Exec /sbin/lilo if needed.
- Return 0 if not need, or -1 if any error.
- */
- PUBLIC int LILO::updateif()
- {
- char path[PATH_MAX];
- makecfgpath ("/boot/map",path);
- long confdate = f_lilo.getdate ();
- long mapdate = file_date (path);
- int ret = 0;
- /* #Specification: lilo / update needed if
- If the file /etc/lilo.conf is newer than /boot/map
- then the command lilo must be executed.
-
- kernel files are also checked. If they are newer than
- /boot/map, lilo has to be executed as this situation
- may yield a non bootable system. Simply copying over
- a kernel image may create a mismatch in /boot/map
- and the actual layout of the kernel on the disk
- */
- int needed = 0;
- if (confdate > mapdate){
- needed = 1;
- }else{
- // Check all kernel to see if they are newer
- // Failing
- for (int i=0; i<confs.getnb(); i++){
- LILO_CONF *c = confs.getitem(i);
- makecfgpath (c->image.get(),path);
- long image_date = file_date (path);
- if (image_date > mapdate){
- needed = 1;
- break;
- }
- }
-
- }
- if (needed){
- char buf[PATH_MAX];
- buf[0] = '\0';
- if (prefix[0] != '\0') sprintf (buf,"-r %s",prefix);
- if (simul_ison()
- || xconf_yesno(MSG_U(T_ACTLILO,"Activating LILO configuration")
- ,MSG_U(Q_ACTLILO,"Activating LILO change the way your\n"
- "machine is booting.\n"
- "Do I activate the configuration ?")
- ,help_lilo)==MENU_YES){
- ret = netconf_system_if ("lilo",buf);
- }else{
- ret = 0;
- }
- }
- return ret;
- }
-
-
- /*
- Check if the lilo command must be executed
- */
- int lilo_update ()
- {
- int ret = 0;
- DAEMON *dae = daemon_find("lilo");
- if (dae != NULL && dae->is_managed()){
- LILO lilo;
- if (lilo.isvalid && lilo.isused) ret = lilo.updateif();
- }
- return ret;
- }
-
- /*
- Add a new kernel to the current configuration
- */
- PUBLIC void LILO::addkernel(
- const char *def_src, // Default path for the kernel
- const char *def_name) // Default name for kernel file
- {
- DIALOG dia;
- SSTRING kernel_src (def_src);
- SSTRING kernel_dst;
- SSTRING label;
- char install = 0;
- dia.newf_str (MSG_R(F_KERNELIMAGE),kernel_src);
- dia.newf_radio (MSG_U(F_HOWBOOT,"How it boots"),install,0
- ,MSG_U(F_NEWDEFAULT,"new default bootable setup"));
- dia.newf_radio (" ",install,1
- ,MSG_U(F_REPLCUR,"replace the current bootable setup"));
- dia.newf_radio (" ",install,2,MSG_U(F_SELSETUP,"selectable setup"));
- dia.newf_str (MSG_R(F_LABEL),label);
- if (prefix != '\0' ){
- kernel_dst.setfrom (prefix);
- kernel_dst.append ("/");
- }
- kernel_dst.append (def_name);
- dia.newf_str (MSG_U(F_WHERETOCOPY,"Where to copy the kernel file")
- ,kernel_dst);
- LILO_PARM newparm = def;
- dia.newf_title ("",MSG_U(F_OPTIONS,"Options"));
- setupparm (dia,newparm);
- int nof = 0;
- while (1){
- int len_prefix = strlen(prefix);
- MENU_STATUS code = dia.edit (
- MSG_U(T_ADDINGKERN,"Adding a new kernel to LILO")
- ,MSG_U(I_ADDINGKERN
- ,"You have already a working LILO\n"
- "and you want to upgrade your kernel")
- ,help_lilo
- ,nof);
- if (code == MENU_CANCEL || code == MENU_ESCAPE){
- break;
- }else if (kernel_src.is_empty()){
- xconf_error (MSG_U(E_KERNNEEDED,"You must specify a kernel file"));
- nof = 0;
- }else if (install != 1
- && label.is_empty()){
- xconf_error (MSG_U(E_LABELNEEDED,"You must specify a label"));
- nof = 4;
- }else if (install != 1
- && getconffromlabel(label.get())!=NULL){
- xconf_error (MSG_U(E_LABELEXIST,"The label is already used"));
- nof = 4;
- }else if (!file_exist(kernel_src.get())){
- xconf_error (MSG_U(E_ENOENT,"File %s does not exist")
- ,kernel_src.get());
- nof = 0;
- }else if (kernel_dst.getlen() <= len_prefix
- || kernel_dst.ncmp(prefix,len_prefix)!=0
- || kernel_dst.get()[len_prefix] != '/'){
- xconf_error (MSG_U(E_BADPATH,"Bad path, must be under %s/")
- ,prefix);
- nof = 5;
- }else if (validate_parm(newparm,def.root.is_empty())==-1){
- nof = 7;
- }else if (kernel_dst.cmp(kernel_src)==0
- || !file_exist(kernel_dst.get())
- || xconf_yesno(MSG_U(T_REPLACE,"Replace existing kernel file")
- ,MSG_U(I_REPLACE,"ok to overwrite it ?")
- ,help_lilo)==MENU_YES){
- file_copy (kernel_src.get(),kernel_dst.get());
- LILO_CONF *conf = confs.getitem(0);
- if (install != 1 || conf == NULL){
- conf = new LILO_CONF;
- if (install == 0){
- confs.insert (0,conf);
- }else{
- confs.add (conf);
- }
- }
- conf->parm = newparm;
- conf->label.setfrom(label);
- conf->image.setfrom(kernel_dst.get()+len_prefix);
- if (save() != -1) lilo_update();
- break;
- }
- }
- }
-
-
- /*
- Let the user install a new kernel he just compiled
- */
- void lilo_addcompil()
- {
- static char std_image[]="/usr/src/linux/arch/i386/boot/zImage";
- if (!file_exist (std_image)){
- xconf_error (MSG_U(E_NOCOMPILED
- ,"No kernel recently compiled available"));
- }else{
- FILE *fin = f_makefile.fopen ("r");
- if (fin != NULL){
- char name[30];
- name[0] = '\0';
- char buf[300];
- int version = -1;
- int patchlevel = -1;
- int sublevel = -1;
- while (fgets(buf,sizeof(buf)-1,fin)!=NULL){
- char *pt = strchr (buf,'=');
- /* #Specification: lilo / /usr/src/linux/Makefile / assumption
- To help lilo admin set a proper name for his
- kernel file, we read /usr/src/linux/Makefile
- to grab PATCHLEVEL and SUBLEVEL. We assume
- that the Makefile has the following lines
- at the beginning.
-
- #
- VERSION = x
- PATCHLEVEL = y
- SUBLEVEL = z
- #
- The order is not important.
- */
- if (pt != NULL){
- pt = str_skip(pt+1);
- if (strncmp(buf,"VERSION",7)==0){
- version = atoi(pt);
- }else if (strncmp(buf,"PATCHLEVEL",10)==0){
- patchlevel = atoi(pt);
- }else if (strncmp(buf,"SUBLEVEL",8)==0){
- sublevel = atoi(pt);
- }
- if (version != -1
- && patchlevel != -1
- && sublevel != -1){
- sprintf (name,"kernel-%d.%d.%d"
- ,version,patchlevel,sublevel);
- break;
- }
- }
- }
- fclose (fin);
- LILO lilo;
- lilo.addkernel(std_image,name);
- }
- }
- }
- /*
- Let the user install a new kernel he got from anywhere
- */
- void lilo_addany()
- {
- LILO lilo;
- lilo.addkernel("","");
- }
-
- /*
- Let the user pick a different default boot configuration
- */
- PUBLIC void LILO::setdefault()
- {
- DIALOG dia;
- for (int i=0; i<confs.getnb(); i++){
- LILO_CONF *c = confs.getitem(i);
- dia.new_menuitem (c->label,c->image);
- }
- while (1){
- int choice = 0;
- MENU_STATUS code = dia.editmenu(
- MSG_U(T_DEFKERN,"Default kernel configuration")
- ,MSG_U(I_DEFKERN,"Pick the configuration which will become\n"
- "the default LILO configuration\n"
- "The first one is currently the default")
- ,help_lilo
- ,choice,0);
- if (code == MENU_QUIT || code == MENU_ESCAPE){
- break;
- }else if (code == MENU_OK){
- if (choice != 0){
- LILO_CONF *c = confs.getitem(choice);
- confs.remove (c);
- confs.insert (0,c);
- if (save() != -1) lilo_update();
- }
- break;
- }
- }
- }
-
- void lilo_setdefault()
- {
- LILO lilo;
- lilo.setdefault();
- }
-
-